//////////////////////////////////////////////////////////////////////
////                                                              ////
////  SysGen.v                                                    ////
////                                                              ////
////                                                              ////
////  This file is part of the "Pico E12" project                 ////
////  http://www.picocomputing.com                                ////
////                                                              ////
////                                                              ////
//////////////////////////////////////////////////////////////////////
////                                                              ////
//// Copyright (C) 2005, Picocomputing, Inc.                      ////
//// http://www.picocomputing.com/                                ////
////                                                              ////
//// This source file may be used and distributed without         ////
//// restriction provided that this copyright statement is not    ////
//// removed from the file and that any derivative work contains  ////
//// the original copyright notice and the associated disclaimer. ////
////                                                              ////
//// This source file is free software; you can redistribute it   ////
//// and/or modify it under the terms of the GNU Lesser General   ////
//// Public License as published by the Free Software Foundation; ////
//// either version 2.1 of the License, or (at your option) any   ////
//// later version.                                               ////
////                                                              ////
//// This source is distributed in the hope that it will be       ////
//// useful, but WITHOUT ANY WARRANTY; without even the implied   ////
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR      ////
//// PURPOSE.  See the GNU Lesser General Public License for more ////
//// details.                                                     ////
////                                                              ////
//// You should have received a copy of the GNU Lesser General    ////
//// Public License along with this source; if not, download it   ////
//// from http://www.opencores.org/lgpl.shtml                     ////
////                                                              ////
////////////////////////////////////////////////////////////////////JF


//Xilinx System Generator for DSP Bridge
`include "PicoDefines.v"

module SysGen(CLOCK, MemRead, MemWrite, MemAddress, DataIn, DataOut);

input CLOCK;                                      //50 MHz External Clock Pin
input MemRead;                                    //Memory Read
input MemWrite;                                   //Memory Write
input [31:1]MemAddress;                           //Memory Address
input [15:0]DataIn;                               //Data In	[Host -> Module]
output [15:0]DataOut;                             //Data Out [Module -> Host]

wire [15:0]StepClockDataOut;                      //Step Clock -> Host
wire [15:0]DataDecoderDataOut;                    //System Generator -> Host
wire [15:0]VFDCMDataOut;                          //Variable Frequency DCM -> Host

wire SysGenClkSelect;                             //Step Clock Source Select
wire SysGenStep;                                  //Step Clock
wire [23:0]SysGen_addr;                           //System Generator Address
wire [7:0]SysGen_bank_sel;                        //System Generator Bank
wire [31:0]SysGen_data_in;                        //System Generator Data <- Host
wire [31:0]SysGen_data_out;                       //System Generator Data -> Host
wire SysGen_clk;                                  //System Generator Step Clock
wire SysGen_pci_clk;                              //System Generator Free Running Oscillator
wire SysGen_pci_clk_nobuf;                        //System Generator Free Running Oscillator without a BUGF
wire SysGen_re;                                   //System Generator Read Enable
wire SysGen_we;                                   //System Generator Write Enable


//-------------------System Generator Clock Synthesizer------------------------------
VariableFrequencyDCM VariableFrequencyDCM(.CLOCKIN(CLOCK), .ClockOutPreBuf(SysGen_pci_clk_nobuf), .ClockOut(SysGen_pci_clk), .MemRead(MemRead), .MemWrite(MemWrite),
                                          .MemAddress(MemAddress[31:1]), .DataIn(DataIn[15:0]), .DataOut(VFDCMDataOut[15:0]));


//------------------System Generator Step Clock Generator----------------------------
SysGenStepClock SysGenStepClock(.SysGen_pci_clk_nobuf(SysGen_pci_clk_nobuf), .SysGen_pci_clk(SysGen_pci_clk), .SysGenStep(SysGenStep), .MemRead(MemRead), .MemWrite(MemWrite),
                                .MemAddress(MemAddress[31:1]), .DataIn(DataIn[15:0]), .DataOut(StepClockDataOut[15:0]));


//------------------System Generator Step Clock Selector-----------------------------
BUFGCTRL SysGenStepClockMUX(.I0(SysGenStep), .I1(SysGen_pci_clk_nobuf), .CE0(~SysGenClkSelect), .CE1(SysGenClkSelect),
                            .S0(~SysGenClkSelect), .S1(SysGenClkSelect), .IGNORE0(1'b1), .IGNORE1(1'b1), .O(SysGen_clk));

//---------------------System Generator Databus Bridge-------------------------------
SysGenDataDecoder SysGenDataDecoder(.MemRead(MemRead), .MemWrite(MemWrite), .MemAddress(MemAddress[31:1]),
                                    .DataIn(DataIn[15:0]), .DataOut(DataDecoderDataOut[15:0]),  
												.SysGenClkSelect(SysGenClkSelect),
                                    .SysGen_addr(SysGen_addr[23:0]), .SysGen_bank_sel(SysGen_bank_sel[7:0]), 
												.SysGen_data_in(SysGen_data_in[31:0]), .SysGen_data_out(SysGen_data_out[31:0]),
												.SysGen_pci_clk(SysGen_pci_clk), .SysGen_re(SysGen_re), .SysGen_we(SysGen_we));


//-----------------------System Generator Black Box----------------------------------
`ifndef ENABLE_SYSGEN_LOOPBACK
sysgen_hw_cosim_interface_black_box sysgen_bb(.addr(SysGen_addr[23:0]),                  //Address
                                              .bank_sel(SysGen_bank_sel[7:0]),           //Bank Select
                                              .data_in(SysGen_data_in[31:0]),            //32 Bit Data In
                                              .data_out(SysGen_data_out[31:0]),          //32 Bit Data Out
                                              .clk(SysGen_clk),                          //Step Clock
                                              .pci_clk(SysGen_pci_clk),                  //Free Running Clock
                                              .re(SysGen_re),                            //Read Enable
                                              .we(SysGen_we));                           //Write Enable
`endif

//---------------------System Generator Debug Loopback----------------------------------
`ifdef ENABLE_SYSGEN_LOOPBACK
SysGenLoopBack SysGenLoopBack(.addr(SysGen_addr[23:0]),                  //Address
                              .bank_sel(SysGen_bank_sel[7:0]),           //Bank Select
                              .data_in(SysGen_data_in[31:0]),            //32 Bit Data In
                              .data_out(SysGen_data_out[31:0]),          //32 Bit Data Out
                              .clk(SysGen_clk),                          //Step Clock
                              .pci_clk(SysGen_pci_clk),                  //Free Running Clock
                              .re(SysGen_re),                            //Read Enable
                              .we(SysGen_we));                           //Write Enable

`endif

//-----------------------------Master Data Out---------------------------------------
assign DataOut[15:0] = (VFDCMDataOut[15:0] | StepClockDataOut[15:0] | DataDecoderDataOut[15:0]);



//------------Diagnostic Taps------------//
`ifdef ENABLE_DEBUG_TAPS
wire [23:0]SysGen_addr_tap;
wire [31:0]SysGen_data_out_tap;
wire [31:0]SysGen_data_in_tap;
wire [7:0]SysGen_bank_sel_tap;
wire SysGen_re_tap;
wire SysGen_we_tap;
wire SysGen_clk_tap;
wire SysGen_pci_clk_tap;

//synthesis attribute KEEP of SysGen_data_out_tap is TRUE;
//synthesis attribute KEEP of SysGen_data_in_tap is TRUE;
//synthesis attribute KEEP of SysGen_re_tap is TRUE;
//synthesis attribute KEEP of SysGen_we_tap is TRUE;
//synthesis attribute KEEP of SysGen_clk_tap is TRUE;
//synthesis attribute KEEP of SysGen_pci_clk_tap is TRUE;
//synthesis attribute KEEP of SysGen_addr_tap is TRUE;
//synthesis attribute KEEP of SysGen_bank_sel_tap is TRUE;

BUF SysGen_re_tap_buf(.I(SysGen_re), .O(SysGen_re_tap));
BUF SysGen_we_tap_buf(.I(SysGen_we), .O(SysGen_we_tap));

BUF clk_tap_buf(.I(SysGen_clk), .O(SysGen_clk_tap));
BUF SysGen_pci_clk_tap_buf(.I(SysGen_pci_clk), .O(SysGen_pci_clk_tap));

BUF SysGen_addr_tap0(.I(SysGen_addr[0]), .O(SysGen_addr_tap[0]));
BUF SysGen_addr_tap1(.I(SysGen_addr[1]), .O(SysGen_addr_tap[1]));
BUF SysGen_addr_tap2(.I(SysGen_addr[2]), .O(SysGen_addr_tap[2]));
BUF SysGen_addr_tap3(.I(SysGen_addr[3]), .O(SysGen_addr_tap[3]));
BUF SysGen_addr_tap4(.I(SysGen_addr[4]), .O(SysGen_addr_tap[4]));
BUF SysGen_addr_tap5(.I(SysGen_addr[5]), .O(SysGen_addr_tap[5]));
BUF SysGen_addr_tap6(.I(SysGen_addr[6]), .O(SysGen_addr_tap[6]));
BUF SysGen_addr_tap7(.I(SysGen_addr[7]), .O(SysGen_addr_tap[7]));
BUF SysGen_addr_tap8(.I(SysGen_addr[8]), .O(SysGen_addr_tap[8]));
BUF SysGen_addr_tap9(.I(SysGen_addr[9]), .O(SysGen_addr_tap[9]));
BUF SysGen_addr_tap10(.I(SysGen_addr[10]), .O(SysGen_addr_tap[10]));
BUF SysGen_addr_tap11(.I(SysGen_addr[11]), .O(SysGen_addr_tap[11]));
BUF SysGen_addr_tap12(.I(SysGen_addr[12]), .O(SysGen_addr_tap[12]));
BUF SysGen_addr_tap13(.I(SysGen_addr[13]), .O(SysGen_addr_tap[13]));
BUF SysGen_addr_tap14(.I(SysGen_addr[14]), .O(SysGen_addr_tap[14]));
BUF SysGen_addr_tap15(.I(SysGen_addr[15]), .O(SysGen_addr_tap[15]));
BUF SysGen_addr_tap16(.I(SysGen_addr[16]), .O(SysGen_addr_tap[16]));
BUF SysGen_addr_tap17(.I(SysGen_addr[17]), .O(SysGen_addr_tap[17]));
BUF SysGen_addr_tap18(.I(SysGen_addr[18]), .O(SysGen_addr_tap[18]));
BUF SysGen_addr_tap19(.I(SysGen_addr[19]), .O(SysGen_addr_tap[19]));
BUF SysGen_addr_tap20(.I(SysGen_addr[20]), .O(SysGen_addr_tap[20]));
BUF SysGen_addr_tap21(.I(SysGen_addr[21]), .O(SysGen_addr_tap[21]));
BUF SysGen_addr_tap22(.I(SysGen_addr[22]), .O(SysGen_addr_tap[22]));
BUF SysGen_addr_tap23(.I(SysGen_addr[23]), .O(SysGen_addr_tap[23]));

BUF SysGen_bank_sel_tap0(.I(SysGen_bank_sel[0]), .O(SysGen_bank_sel_tap[0]));
BUF SysGen_bank_sel_tap1(.I(SysGen_bank_sel[1]), .O(SysGen_bank_sel_tap[1]));
BUF SysGen_bank_sel_tap2(.I(SysGen_bank_sel[2]), .O(SysGen_bank_sel_tap[2]));
BUF SysGen_bank_sel_tap3(.I(SysGen_bank_sel[3]), .O(SysGen_bank_sel_tap[3]));
BUF SysGen_bank_sel_tap4(.I(SysGen_bank_sel[4]), .O(SysGen_bank_sel_tap[4]));
BUF SysGen_bank_sel_tap5(.I(SysGen_bank_sel[5]), .O(SysGen_bank_sel_tap[5]));
BUF SysGen_bank_sel_tap6(.I(SysGen_bank_sel[6]), .O(SysGen_bank_sel_tap[6]));
BUF SysGen_bank_sel_tap7(.I(SysGen_bank_sel[7]), .O(SysGen_bank_sel_tap[7]));

BUF SysGen_data_in_tap0(.I(SysGen_data_in[0]), .O(SysGen_data_in_tap[0]));
BUF SysGen_data_in_tap1(.I(SysGen_data_in[1]), .O(SysGen_data_in_tap[1]));
BUF SysGen_data_in_tap2(.I(SysGen_data_in[2]), .O(SysGen_data_in_tap[2]));
BUF SysGen_data_in_tap3(.I(SysGen_data_in[3]), .O(SysGen_data_in_tap[3]));
BUF SysGen_data_in_tap4(.I(SysGen_data_in[4]), .O(SysGen_data_in_tap[4]));
BUF SysGen_data_in_tap5(.I(SysGen_data_in[5]), .O(SysGen_data_in_tap[5]));
BUF SysGen_data_in_tap6(.I(SysGen_data_in[6]), .O(SysGen_data_in_tap[6]));
BUF SysGen_data_in_tap7(.I(SysGen_data_in[7]), .O(SysGen_data_in_tap[7]));
BUF SysGen_data_in_tap8(.I(SysGen_data_in[8]), .O(SysGen_data_in_tap[8]));
BUF SysGen_data_in_tap9(.I(SysGen_data_in[9]), .O(SysGen_data_in_tap[9]));
BUF SysGen_data_in_tap10(.I(SysGen_data_in[10]), .O(SysGen_data_in_tap[10]));
BUF SysGen_data_in_tap11(.I(SysGen_data_in[11]), .O(SysGen_data_in_tap[11]));
BUF SysGen_data_in_tap12(.I(SysGen_data_in[12]), .O(SysGen_data_in_tap[12]));
BUF SysGen_data_in_tap13(.I(SysGen_data_in[13]), .O(SysGen_data_in_tap[13]));
BUF SysGen_data_in_tap14(.I(SysGen_data_in[14]), .O(SysGen_data_in_tap[14]));
BUF SysGen_data_in_tap15(.I(SysGen_data_in[15]), .O(SysGen_data_in_tap[15]));
BUF SysGen_data_in_tap16(.I(SysGen_data_in[16]), .O(SysGen_data_in_tap[16]));
BUF SysGen_data_in_tap17(.I(SysGen_data_in[17]), .O(SysGen_data_in_tap[17]));
BUF SysGen_data_in_tap18(.I(SysGen_data_in[18]), .O(SysGen_data_in_tap[18]));
BUF SysGen_data_in_tap19(.I(SysGen_data_in[19]), .O(SysGen_data_in_tap[19]));
BUF SysGen_data_in_tap20(.I(SysGen_data_in[20]), .O(SysGen_data_in_tap[20]));
BUF SysGen_data_in_tap21(.I(SysGen_data_in[21]), .O(SysGen_data_in_tap[21]));
BUF SysGen_data_in_tap22(.I(SysGen_data_in[22]), .O(SysGen_data_in_tap[22]));
BUF SysGen_data_in_tap23(.I(SysGen_data_in[23]), .O(SysGen_data_in_tap[23]));
BUF SysGen_data_in_tap24(.I(SysGen_data_in[24]), .O(SysGen_data_in_tap[24]));
BUF SysGen_data_in_tap25(.I(SysGen_data_in[25]), .O(SysGen_data_in_tap[25]));
BUF SysGen_data_in_tap26(.I(SysGen_data_in[26]), .O(SysGen_data_in_tap[26]));
BUF SysGen_data_in_tap27(.I(SysGen_data_in[27]), .O(SysGen_data_in_tap[27]));
BUF SysGen_data_in_tap28(.I(SysGen_data_in[28]), .O(SysGen_data_in_tap[28]));
BUF SysGen_data_in_tap29(.I(SysGen_data_in[29]), .O(SysGen_data_in_tap[29]));
BUF SysGen_data_in_tap30(.I(SysGen_data_in[30]), .O(SysGen_data_in_tap[30]));
BUF SysGen_data_in_tap31(.I(SysGen_data_in[31]), .O(SysGen_data_in_tap[31]));

BUF SysGen_data_out_tap0(.I(SysGen_data_out[0]), .O(SysGen_data_out_tap[0]));
BUF SysGen_data_out_tap1(.I(SysGen_data_out[1]), .O(SysGen_data_out_tap[1]));
BUF SysGen_data_out_tap2(.I(SysGen_data_out[2]), .O(SysGen_data_out_tap[2]));
BUF SysGen_data_out_tap3(.I(SysGen_data_out[3]), .O(SysGen_data_out_tap[3]));
BUF SysGen_data_out_tap4(.I(SysGen_data_out[4]), .O(SysGen_data_out_tap[4]));
BUF SysGen_data_out_tap5(.I(SysGen_data_out[5]), .O(SysGen_data_out_tap[5]));
BUF SysGen_data_out_tap6(.I(SysGen_data_out[6]), .O(SysGen_data_out_tap[6]));
BUF SysGen_data_out_tap7(.I(SysGen_data_out[7]), .O(SysGen_data_out_tap[7]));
BUF SysGen_data_out_tap8(.I(SysGen_data_out[8]), .O(SysGen_data_out_tap[8]));
BUF SysGen_data_out_tap9(.I(SysGen_data_out[9]), .O(SysGen_data_out_tap[9]));
BUF SysGen_data_out_tap10(.I(SysGen_data_out[10]), .O(SysGen_data_out_tap[10]));
BUF SysGen_data_out_tap11(.I(SysGen_data_out[11]), .O(SysGen_data_out_tap[11]));
BUF SysGen_data_out_tap12(.I(SysGen_data_out[12]), .O(SysGen_data_out_tap[12]));
BUF SysGen_data_out_tap13(.I(SysGen_data_out[13]), .O(SysGen_data_out_tap[13]));
BUF SysGen_data_out_tap14(.I(SysGen_data_out[14]), .O(SysGen_data_out_tap[14]));
BUF SysGen_data_out_tap15(.I(SysGen_data_out[15]), .O(SysGen_data_out_tap[15]));
BUF SysGen_data_out_tap16(.I(SysGen_data_out[16]), .O(SysGen_data_out_tap[16]));
BUF SysGen_data_out_tap17(.I(SysGen_data_out[17]), .O(SysGen_data_out_tap[17]));
BUF SysGen_data_out_tap18(.I(SysGen_data_out[18]), .O(SysGen_data_out_tap[18]));
BUF SysGen_data_out_tap19(.I(SysGen_data_out[19]), .O(SysGen_data_out_tap[19]));
BUF SysGen_data_out_tap20(.I(SysGen_data_out[20]), .O(SysGen_data_out_tap[20]));
BUF SysGen_data_out_tap21(.I(SysGen_data_out[21]), .O(SysGen_data_out_tap[21]));
BUF SysGen_data_out_tap22(.I(SysGen_data_out[22]), .O(SysGen_data_out_tap[22]));
BUF SysGen_data_out_tap23(.I(SysGen_data_out[23]), .O(SysGen_data_out_tap[23]));
BUF SysGen_data_out_tap24(.I(SysGen_data_out[24]), .O(SysGen_data_out_tap[24]));
BUF SysGen_data_out_tap25(.I(SysGen_data_out[25]), .O(SysGen_data_out_tap[25]));
BUF SysGen_data_out_tap26(.I(SysGen_data_out[26]), .O(SysGen_data_out_tap[26]));
BUF SysGen_data_out_tap27(.I(SysGen_data_out[27]), .O(SysGen_data_out_tap[27]));
BUF SysGen_data_out_tap28(.I(SysGen_data_out[28]), .O(SysGen_data_out_tap[28]));
BUF SysGen_data_out_tap29(.I(SysGen_data_out[29]), .O(SysGen_data_out_tap[29]));
BUF SysGen_data_out_tap30(.I(SysGen_data_out[30]), .O(SysGen_data_out_tap[30]));
BUF SysGen_data_out_tap31(.I(SysGen_data_out[31]), .O(SysGen_data_out_tap[31]));

`endif

endmodule